﻿using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Cimbalino.Phone.Toolkit.Services;
using DepSoft.Mobile.WP8.FollwIt.Framework.Interfaces;
using DepSoft.Mobile.WP8.FollwIt.Model;
using Microsoft.Phone.Tasks;

namespace DepSoft.Mobile.WP8.FollwIt.Framework
{
    public class SecurityService : ISecurityService
    {
        private IAsyncStorageService _asyncStorageService;
        private Security _security;

        public SecurityService(IAsyncStorageService asyncStorageService)
        {
            _asyncStorageService = asyncStorageService;
        }

        private async Task<bool> SecurityServiceExists()
        {
            bool exists = await _asyncStorageService.FileExistsAsync(Constants.SECURITYUSERNAME);
            if(exists)
                exists = await _asyncStorageService.FileExistsAsync(Constants.SECURITYPASSWORD);

            return exists;
        }

        public async Task ClearCredentialsAsync()
        {
            _security = null;
            await _asyncStorageService.DeleteFileAsync(Constants.SECURITYUSERNAME);
            await _asyncStorageService.DeleteFileAsync(Constants.SECURITYPASSWORD);
        }

        public async Task SaveCredentialsAsync(Security security)
        {
            //Convert Password and Salt values to byte[] arrays
            byte[] userNameByte = Encoding.UTF8.GetBytes(security.UserName);
            byte[] passwordByte = Encoding.UTF8.GetBytes(security.Password);

            //Encrypt Password and Salt byte[] arrays using Protect() method
            byte[] hashedUserName = ProtectedData.Protect(userNameByte, null);
            byte[] hashedPassword = ProtectedData.Protect(passwordByte, null);

            await _asyncStorageService.WriteAllBytesAsync(Constants.SECURITYUSERNAME, hashedUserName);
            await _asyncStorageService.WriteAllBytesAsync(Constants.SECURITYPASSWORD, hashedPassword);

            _security = security;
        }

        public async Task<Security> GetCredentialsAsync()
        {
            if (!ReferenceEquals(_security, null))
                return _security;

            bool exists = await this.SecurityServiceExists();
            if (exists)
            {
                byte[] hashedUserName = await _asyncStorageService.ReadAllBytesAsync(Constants.SECURITYUSERNAME);
                byte[] hashedPassword = await _asyncStorageService.ReadAllBytesAsync(Constants.SECURITYPASSWORD);

                if (!ReferenceEquals(hashedUserName, null) && !ReferenceEquals(hashedPassword, null))
                {
                    //Decrypt Password and Salt byte[] arrays using Unprotect() method
                    byte[] userNameByte = ProtectedData.Unprotect(hashedUserName, null);
                    byte[] passwordByte = ProtectedData.Unprotect(hashedPassword, null);

                    //Convert byte[] arrays to strings and display in the text boxes
                    _security = new Security();
                    _security.UserName = Encoding.UTF8.GetString(userNameByte, 0, userNameByte.Length);
                    _security.Password = Encoding.UTF8.GetString(passwordByte, 0, passwordByte.Length);
                }                
            }

            return _security;
        }
    }
}
